package com.licq.ldoc.writer.visitor.example;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.sql.Time;
import java.sql.Timestamp;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.beanutils.PropertyUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.licq.ldoc.domain.AttributeType;
import com.licq.ldoc.domain.AttributeTypeConverter;
import com.licq.ldoc.utils.BeanUtils;
import com.lowagie.text.BadElementException;

/**
 * 
 * @author liujian
 *
 */
@SuppressWarnings("serial")
public abstract class Exampler {
	private static transient Log logger = LogFactory.getLog(Exampler.class);
	
	private AttributeTypeConverter converter = new AttributeTypeConverter();
	
	protected static final Map<Class<?>, String> DEFAULT_VALUE = new HashMap<Class<?>, String>() {
		{
			put(Integer.class, "3");
			put(Short.class, "4");
			put(Long.class, "5");
			put(Character.class, "a");
			put(Float.class, "30.50");
			put(Double.class, "80.50");
			put(Byte.class, "2");
			put(Boolean.class, "true");
			put(String.class, "some value");
			put(BigDecimal.class, "60.50");
			put(BigInteger.class, "150");
			put(Date.class, "2008-08-08 08:08:08");
			put(Calendar.class, "2008-08-08 08:08:08");
			put(java.sql.Date.class, "2008-08-08");
			put(Time.class, "08:08:08");
			put(Timestamp.class, "2008-08-08 08:08:08");
			put(Class.class, "com.derbysoft.Bean");
			put(Object.class, "some value");
		}
	};

	public abstract void create() throws BadElementException;
	
	protected static Object getPropertyValue(Object object, String property) {
		try {
			//若存在getter,则优先考虑getter,可能存在逻辑
			return PropertyUtils.getProperty(object, property);
		} catch (Exception e) {
			try {
				return BeanUtils.getDeclaredFieldValue(object, property);
			} catch (NoSuchFieldException e1) {
				if (logger.isErrorEnabled()) {
					logger.error(String.format("class[%s] has no field[%s].", 
							object.getClass().getName(),
							property
						)
					);
				}
				return null;
			}
		}
	}
	
	protected String getDefaultPropertyValue(AttributeType type) {
		Class<?> clazz = converter.convert(type);
		if (clazz != null) {
			if (clazz != Enum.class) {
				return DEFAULT_VALUE.get(clazz);
			} else {
				return getDefaultEnumPropValue();
			}
		} else {
			return null;
		}
	}
	
	protected String getDefaultEnumPropValue() {
		return null;
	}
	
}
